/**
 * 功能： 下载 M3U8 地址的视频并保存成 MP4 格式
 * 说明： 本模块修改自NPM模块 m3u8-to-mp4 ， 原模块地址： https://www.npmjs.com/package/m3u8-to-mp4
 *  
 */
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegPath);
let log = require('single-line-log').stdout;
const { calcTimeInterval } = require('../../utils/time')

/**
 * A class to convert M3U8 to MP4
 * @class
 */
class m3u8ToMp4Converter {
    /**
     * Sets the input file
     * @param {String} filename M3U8 file path. You can use remote URL
     * @returns {Function}
     */

    constructor(){
        this.progress={}
        this.timer = null
        this.done = 0
    }

    setInputFile(filename) {
        if (!filename) throw new Error("您必须指定M3U8文件地址");
        this.M3U8_FILE = filename;

        return this;
    }

    /**
     * 计算下载时间
     */
    timing (){
        const startTime = new Date()
        this.timer = setInterval(()=>{
            const timeInterval = calcTimeInterval(startTime, new Date())
            const { hours, minutes, seconds } = timeInterval
            const time = `${hours}:${minutes}:${seconds}`
            // 下载进度
            const progress = this.progress.timemark ? ` 已经下载影片时长${this.progress.timemark}`:'下载初始化' 
            const {done,total} = this.progress
            const percent = done + total > 0 ? (done * 100 / total).toFixed(2) : '0'
            const mbps = this.progress.currentKbps ? `${(Number(this.progress.currentKbps) / 1024).toFixed(2)}MB/s` : '0' 
            log(`下载进度:${this.OUTPUT_FILE}   ${percent}%   ${done||0}/${total}   ${mbps}  ${time}`);
        },1000)
    }

    // 清除计时
    endTiming(){
        clearInterval(this.timer);
        this.timer =null
    }

    // 获取M3u8总资源数
    async getM3u8Info(){
        const that = this
        fetch(this.M3U8_FILE)
        .then(res=>  res.text() )
        .then(text=>{
            that.progress.total = text.match(/.ts\n/g).length
        }).catch(e=>{
            console.log(e)
        })
    }

    /**
     * Sets the output file
     * @param {String} filename Output file path. Has to be local :)
     * @returns {Function}
     */
    setOutputFile(filename) {
        if (!filename) throw new Error("您必须指定文件路径和名称");
        this.OUTPUT_FILE = filename;

        return this;
    }

    /**
     * Starts the process
     */
    start() {
        return new Promise((resolve, reject) => {
            if (!this.M3U8_FILE || !this.OUTPUT_FILE) {
                reject(new Error("您必须指定输入和输出文件"));
                return;
            }

            // 开始计时
            this.timing()
            this.getM3u8Info()
            const that = this

            console.log('=========================');
            console.log(this.OUTPUT_FILE, '文件名')
            ffmpeg(this.M3U8_FILE)
                .on("error", error => {
                    reject(new Error(error));
                })
                .on('progress', function (progress) {
                    that.done += 1
                    that.progress = 
                    {...that.progress,
                        ...progress,
                        done:that.done
                    }
                })
                .on("end", () => {
                    log('下载进度: 已完成 100%。\n');
                    this.endTiming()
                    this.done=0
                    console.log('=========================');
                    resolve();
                })
                .outputOptions("-c copy")
                .outputOptions("-bsf:a aac_adtstoasc")
                .output(this.OUTPUT_FILE)
                .run();
        });
    }
}

module.exports = m3u8ToMp4Converter;

